/**
* transfer组件初步封装，后续根据实际业务改进
* Date 2023-08-15 17:10
* Date 2023-10-12 10  修改了代码，移除了全选复选框及>>  << 两个按钮
* 备注：
*/
<template>
  <div style="text-align: center; width: 100%; height: 420px; padding: 0 20px">
    <div style="float: left">
      <div style="width: 230px;">{{ titleLeft }}</div>
      <div class="box transfer-left">
        <tree-List
          ref="leftTreeRef"
          class="test2"
          :companyData="myLeftData"
          :defaultCheckedKeys="keys"
          :isShow="true"
          :defaultProps="defaultProps"
          @filter-node-method="filterNode"
          @handleNodeClick="handleNodeClick"
          @handleCheckBoxClick="handleCheckBoxClick"
        />
      </div>
      <!--<div style="width: 230px; text-align: left;">
        <el-checkbox v-model="checkAllLeft" label="全选" @change="checkAllLeft" />
      </div>-->
    </div>
    <div class="transfer-center">
      <!--<el-button type="primary" plain
                 class="el-transfer__buttons btn"
                 v-bind:disabled="rightData.length == 0"
                 @click="dLeftClick" :icon="DArrowLeft" />-->
      <el-button type="primary" plain
                 class="el-transfer__buttons btn"
                 v-bind:disabled="tempRight.length == 0"
                 @click="leftClick" :icon="ArrowLeft" />
      <el-button type="primary" plain
                 class="el-transfer__buttons btn"
                 v-bind:disabled="tempLeft.length == 0"
                 @click="rightClick" :icon="ArrowRight" />
      <!--<el-button type="primary" plain
                 class="el-transfer__buttons btn"
                 v-bind:disabled="myLeftData.length == 0"
                 @click="dRightClick" :icon="DArrowRight" />-->
    </div>
    <div style="float: left">
      <div style="width: 230px">{{ titleRight }}</div>
      <div class="box transfer-right">
        <tree-List
          ref="rightTreeRef"
          class="test2"
          :isShow="true"
          :companyData="rightData"
          :defaultProps="defaultProps"
          @handleNodeClick="handleRightNodeClick"
          @handleCheckBoxClick="handleRightCheckBoxClick"
        />
      </div>
    </div>
  </div>
</template>

<script lang="ts" setup>
  import { ref, toRaw } from 'vue'
  import { ArrowRight, ArrowLeft, DArrowRight, DArrowLeft } from '@element-plus/icons-vue'
  import treeList from '@/views/components/TreeList/index.vue'

  const props = defineProps<{ leftData: Array; defaultProps?: Array; title?: Array}>()
  const emits = defineEmits([
    'handleNodeClick',
    'handleRightNodeClick'
  ])
  const leftTreeRef = ref();
  const rightTreeRef = ref();
  const rightData = ref([]) // 右边的数据集
  const myLeftData = ref(props.leftData) // 左边的数据集
  const titleLeft = ref(props.title[0])
  const titleRight = ref(props.title[1])
  const idsLeft = ref([]) // 左边被选择的id集合
  const idsRight = ref([]) // 右边被选择的id集合
  const tempLeft = ref([]) // 左边临时数据集
  const tempRight = ref([]) // 右边临时数据集
  const checkAll = ref(false) // 左边是否全选
  const keys = ref([]) // 左边是否全选
  const checkedAll = () => {
    let id = myLeftData.value[0].id // 获取左边数据集第一个元素的id
    keys.value = checkAll.value ? [id] : ['']
    if(!checkAll.value) {
      setChecked(id, false, true)
    } else {
      idsLeft.value = getTreeId(myLeftData.value[0], [])
      tempLeft.value = treeFilter(myLeftData.value, node => idsLeft.value.includes(node.id))
    }
  }
  // 穿透调用子组件的setChecked方法
  // 三个参数分别为  树节点key(此处为id)， 是否选中， 是否遍历子节点
  const setChecked = (key, checked, deep) => {
    leftTreeRef.value.setChecked(key, checked, deep)
  }
  // 获取选择的数据中的id
  const getId = (arr) => {
    let temp = []
    arr.forEach(a =>{
      temp.push(a.id)
    })
    return temp
  }
  const getTreeId = (data, arr) => {
    if(data.id != undefined){
      arr.push(data.id)
    }
    if (data.children && data.children.length) {
      for (let item of data.children) {
        arr.push(item.id)
        if (item.children && item.children.length) {
          getTreeId(item.children, arr)
        }
      }
    }else{
      for (let item of data) {
        arr.push(item.id)
      }
    }

    return arr
  }
  const treeFilter = (tree, func) => {
    return tree.map(node => ({ ...node })).filter(node => {
      node.children = node.children && treeFilter(node.children, func)
      return func(node) || (node.children && node.children.length)
    })
  }
  const deletedId = (data, ids) => {
    for (var m = 0, n = data.length; m < n; m++) {
      for (var i = 0, j = ids.length; i <j; i++) {
        if (data[m] && data[m].id === ids[i]) {
          data.splice(m, 1)
        }
      }
      // console.log(data[m])
      if (data[m] && data[m].children != undefined) {
        deletedId(data[m].children, ids)
      }
    }
    return data
  }
  const deletedAll = (data) => {
    for (var m = data.length-1, n = 0; m >= n; m--) {
      data.splice(m, 1)
    }
    return data
  }

  // 合并数组的方法
  const mergeTrees = (tree1, tree2) => {
    const mergedTree = [...tree1]
    tree2.forEach((rightNode) => {
      const leftNode = mergedTree.find(node => node.id === rightNode.id)
      if (leftNode) {
        if (leftNode.children && rightNode.children) {
          leftNode.children = mergeTrees(leftNode.children, rightNode.children)
        } else if (!leftNode.children && rightNode.children) {
          leftNode.children = rightNode.children
        }
      } else {
        mergedTree.push(rightNode)
      }
    })
    return mergedTree;
  }
  // 排序方法
  const sort = (node) => {
    if (node.children) {
      node.children.sort((a, b) => {
        if (a.id > b.id) {
          return -1
        }
        if (a.id < b.id) {
          return 1
        }
        return 0
      })
      node.children.forEach(sort)
    }
    return node
  }

  // 树节点被点击
  const handleNodeClick = (data, node, treeNode, e) => {
    emits('handleNodeClick', data, node, treeNode, e)
  }
  // 左边复选框被点击
  const handleCheckBoxClick = (node, checkedNodes, permNodes) => {
    idsLeft.value = getId(permNodes)
    tempLeft.value = treeFilter(myLeftData.value, node => idsLeft.value.includes(node.id))
  }
  const handleRightNodeClick = (data, node, treeNode, e) => {
    emits('handleRightNodeClick', data, node, treeNode, e)
  }
  // 右边复选框被点击
  const handleRightCheckBoxClick = (node, checkedNodes, permNodes) => {
    idsRight.value = getId(permNodes)
    tempRight.value = treeFilter(rightData.value, node => idsRight.value.includes(node.id))
  }
  const rightClick = () => {
    myLeftData.value = deletedId(myLeftData.value, idsLeft.value)
    if (rightData.value.length == 0) {
      rightData.value = tempLeft.value
    } else {
      let temp  = mergeTrees(rightData.value, tempLeft.value);
      const sortedData = [...rightData.value];
      sortedData.forEach(sort);
      rightData.value = sortedData
    }
    tempLeft.value = []
    leftTreeRef.value.setSearch()
  }
  // const dRightClick = () => {
  //   rightData.value = JSON.parse(JSON.stringify(myLeftData.value))
  //   myLeftData.value= deletedAll(myLeftData.value)
  //   leftTreeRef.value.getFilterDate()
  // }
  const leftClick = () => {
    rightData.value = deletedId(rightData.value, idsRight.value)
    if (myLeftData.value.length == 0) {
      myLeftData.value = tempRight.value
    } else {
      let temp  = mergeTrees(myLeftData.value, tempRight.value);
      const sortedData = [...myLeftData.value];
      sortedData.forEach(sort);
      myLeftData.value = sortedData
    }
    tempRight.value = []
    rightTreeRef.value.setSearch()
  }
  // const dLeftClick = () => {
  //   myLeftData.value = JSON.parse(JSON.stringify(rightData.value))
  //   rightData.value = deletedAll(rightData.value)
  // }

  const value = ref([])
  const getParams = () => {
    const data = toRaw(rightData.value)
    return Object.keys(data).reduce((pre, cur) => {
      return Object.assign(pre, { [cur]: data[cur] || undefined })
    }, {})
  }
  defineExpose({
    getParams
  })
</script>

<style lang="less" scoped>
  .el-transfer /deep/ .el-transfer__buttons {
    display: inline-flex;
    justify-content: center;
    align-items: center;
    flex-direction: column;
    .el-button {
      margin-left: 0;
      margin-bottom: 10px;
      .el-icon {
        color: #000;
      }
    }
  }
  .transfer-center {
    width: 80px;
    float: left;
    height: 160px;
    padding: 180px 20px;
    position: relative;
    .btn {
      width: 46px;
      height: 33px;
      padding-right: 5px;
      padding-left: 5px;
      margin-bottom: 10px;
      margin-left: 0;
    }
  }
  .box {
    width: 230px;
    height: 400px;
    float: left;
    border: #2F7DF1 1px solid;
    border-radius: 4px;
    overflow-y: scroll;
  }
  .box::-webkit-scrollbar {
    display: none;
  }
</style>
